import httplib, urllib
import time
import XmlParser
import json
import re

def to_localtime(rfc3339):
  if rfc3339.find("T")==-1:
    r =  re.compile("(\d\d\d\d)-(\d\d)-(\d\d)")
  else:
    r = re.compile("(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)\.(\d\d\d)(.*)")
  m = r.match(rfc3339)
  cnt = len(m.groups())
  if cnt>6:
    cnt = 6;
  t = [0, 0, 0, 0, 0, 0]
  for i in range(cnt):
    t[i] = int(m.group(i+1))
  return time.mktime((t[0], t[1], t[2], t[3], t[4], t[5], 0, 0, -1))
#  todo: fix rfc3339 later 
#  tz = abs(time.timezone)/3600 
#  mz = (abs(time.timezone)%3600)/60
#  if time.timezone<0:
#    tz = -tz
#    mz = -mz
#  tz = tz - time.daylight    
#  cv = 0
#  mv = 0
#  if m.group(8) == 'Z':
#    cv = tz
#  else:
#    sr = re.compile("([+|-]\d\d):(\d\d)")
#    sm = sr.match(m.group(8))
#    cv = int(sm.group(1))+tz 
#    mv = int(sm.group(2))+mz
#  M = M - mv
#  if M < 0:
#    M = 60 + M
#    H = H - 1
#  elif M > 60:
#    M = M - 60
#    H = H + 1
#  if H < 0:
#    H = H + 24
#    d = d - 1
#  elif H > 24:
#    H = H - 24
#    d = d + 1
#  if d < 0:
#    d = 

  

class GoogleAccountAPI:
    def __init__(self, email=None, password=None, source="CMU-GoogleAccountAPI-1"):
      self._auth = None
      self._resp = None
      self._error = None
      self._gsessionid = None
      if email != None and password != None:
        self.client_login(email, password, source)
        
    def client_login(self, email, password, source="CMU-GoogleAccountAPI-1"):
#      print "ClientLogin:" + email + "," + password
      if email == None or password == None:
        raise "email or password can not be empty"
      data = urllib.urlencode({"Email":email, "Passwd":password, "source":source, "service":"cl", "accountType": "HOSTED_OR_GOOGLE"})
#      print "request data=" + data
      header = {"Content-type": "application/x-www-form-urlencoded", "Content-length": len(data)}
      self._error = None
      try:
        conn = httplib.HTTPSConnection("www.google.com")
#      print "https conn ok"
        conn.request("post", "/accounts/ClientLogin", data, header)
#      print "request ok"
        cresp = conn.getresponse()
#      print "resp ok"
#        print cresp.msg
        self._resp = cresp.read()
#      print "read ok:" + self._resp 
        self._auth = self._resp[self._resp.rindex("Auth=") + 5:]
      except:
        self._error = "ClientLogin Fails:" + self._resp
#        raise "ClientLogin Fails:"+self._resp
        
    def get_auth(self):
      return self._auth
    
    def get_error(self):
      return self._error
    
    def post_gdata(self, url_string, data, use_json=True):
      if self._auth == None:
        raise "You must login first"
      op = urllib.URLopener()
      op.addheaders = [("Authorization", "GoogleLogin auth=%s" % self._auth)]
      self._error = None
      if use_json:
        if url_string.find("?") == - 1:
          url_string = url_string + "?alt=json"
        else:
          url_string = url_string + "&alt=json"
      try:
        f = op.open(url_string, data)
        self._resp = f.read()        
      except:
        self._error = "request atom fails: %s" % self._resp
        self._resp = None
#      print self._resp
      if use_json:
        return self.parseJSON(self._resp)
      return self.parseXML(self._resp)      
    
    def request_gdata(self, url_string, use_json=True):
      if self._auth == None:
        raise "You must login first"
      op = urllib.URLopener()
      op.addheaders = [("Authorization", "GoogleLogin auth=%s" % self._auth)]
      self._error = None
      if use_json:
        if url_string.find("?") == - 1:
          url_string = url_string + "?alt=json"
        else:
          url_string = url_string + "&alt=json"      
      if self._gsessionid != None:
        if url_string.find("?") == -1:
          url_string = url_string +"?gsessionid="+self._gsessionid
        else:
          url_string = url_string +"&gsessionid="+self._gsessionid
      try:
        f = op.open(url_string)
        self._resp = f.read()    
        f.close()    
      except IOError, (error, errcode, errmsg, headers):
        if errcode == 302:
          self.handle_redirect(headers, use_json)
        else:  
          self._error = "request atom fails: %s" % self._resp
          self._resp = None
          raise IOError, (self._error)
#      print self._resp  
      if use_json:
        return self.parseJSON(self._resp)
      return self.parseXML(self._resp)
      
    def handle_redirect(self, headers, use_json):
      location = None
      if headers.has_key("location"):
        location = headers["location"]
      elif headers.has_key("uri"):
        location = headers["uri"]
#      print "=========302:%s"%location
      if location != None:
        idx = location.find("gsessionid=")         
        if idx>-1:
          self._gsessionid = location[idx + 11 :]
        op = urllib.URLopener()
        op.addheaders = [("Authorization", "GoogleLogin auth=%s" % self._auth)]
        f = op.open(location)
        self._resp = f.read()    
        f.close() 
      
    def parseJSON(self, json_data):
#      print json_data
      json_rd = json.JsonReader()
      return json_rd.read(json_data)      
                         
    def parseXML(self, xml):
      parser = XmlParser.XMLParser()
      parser.parseXML(xml)     
      return parser.root     
     
def main():
  start = time.time()
  print "GooglaAccountAPI Test: start at %d sec" % start  
  gacc = GoogleAccountAPI("edu", "")
  print "Auth=%s" % gacc.get_auth()
  if gacc.get_auth() == None:
    print "Error=%s" % gacc.get_error()  
  end = time.time()
  print "GoogleAccountAPI Test pass: end at %(end) sec, total=%(total) seconds" % {"end":end, "total":(end - start)}

#  start = time()
#  print "GooglaAccountAPI fail Test: start at %d sec" % start  
#  gacc = GoogleAccountAPI("tony.lin@west.cmu.edu", "")
#  print "Auth=%s" % gacc.get_auth()

#  end = time()
#  print "GoogleAccountAPI fail Test pass: end at %(end) sec, total=%(total) seconds" % {"end":end, "total":(end - start)}
#  
if __name__ == "__main__":
  main()
  
  